package com.nextpro.media.encoder;

import com.nextpro.media.interfaces.ProcessPublisher;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 14-2-18.
 */
public class W32Encoder implements Encoder {
    private String ffmpegPath = "ffmpeg.exe";
    private ProcessPublisher publisher;
    private int lastProcess = 0;
    private int currentProcess = 0;
    private long duration = 0;
    private long durationTotal = 0;

    private String DURATION_REGEX = "Duration: ([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2})";
    private String CURRENT_TIME_REGEX = "time=([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2}) bitrate=(.*kbits/s)";
    private Pattern pattern_time = Pattern.compile(CURRENT_TIME_REGEX);

    public W32Encoder(ProcessPublisher processPublisher) {
        this.publisher =processPublisher;
    }

    @Override
    public boolean encode(String oldfilepath) {
        List<String> commend = new java.util.ArrayList<String>();
        File file = new File(oldfilepath);

        if (!file.exists()) {
            return false;
        }
        String newFilePath = oldfilepath.replaceAll(".[a-z]{3}$", ".mp4");
        file = new File(newFilePath);
        if (file.exists()) {
            return false;
        }
        if (ffmpegPath == null) {
            if (!_fixFFmpgePath()) {
                System.out.println("ffmpeg_win32 not found!");
				return false;
            }
        }else{
			File fileffmpeg = new File(ffmpegPath);
			if(fileffmpeg.exists()){
				System.out.println("file was found");
				ffmpegPath = fileffmpeg.getAbsolutePath();
			}else{
				System.out.println(fileffmpeg.getAbsolutePath());
					System.out.println("file not found");
			}
		}
        mediaEncoding(oldfilepath, newFilePath);
        return true;
    }

    private void doWithString(String s) {
        if (this.publisher == null){
            System.out.println(s);
            return;
        }
        if (s.contains("Duration")) {
            Pattern pattern = Pattern.compile(DURATION_REGEX);
            Matcher matcher = pattern.matcher(s);
            while (matcher.find()) {
                int hour = Integer.parseInt(matcher.group(1));

                int minute = Integer.parseInt(matcher.group(2));

                int second = Integer.parseInt(matcher.group(3));

                int minisecond = Integer.parseInt(matcher.group(4));

                durationTotal = (((hour * 60) + minute) * 60 + second) * 100 + minisecond;
            }
        }

        Matcher matcher = pattern_time.matcher(s);
        String info = "";
        while (matcher.find()) {
            int hour = Integer.parseInt(matcher.group(1));

            int minute = Integer.parseInt(matcher.group(2));

            int second = Integer.parseInt(matcher.group(3));

            int minisecond = Integer.parseInt(matcher.group(4));

            duration = (((hour * 60) + minute) * 60 + second) * 100 + minisecond;
            info = matcher.group(5);

        }
        currentProcess = (int) Math.round(1.0 * duration / durationTotal * 100);
        if (currentProcess > lastProcess) {
            this.publisher.updateSingleProcess(currentProcess - lastProcess);
            lastProcess = currentProcess;
        }
        this.publisher.updateSpeed(info);
    }

    public  void mediaEncoding( String srcPath, String desFile) {
        //Java调用CMD命令时,不能有空格
        String srcpath = "\"" + srcPath + "\"";
        String desfile = "\"" + desFile + "\"";
//        System.out.println(srcpath);
//        System.out.println(desfile);
//        Runtime rt = Runtime.getRuntime();
//        String command = String.format("cmd /c %s %s", ffmpegPath, srcpath);
//        System.out.println(command);
//        Process p = null;
        try {
            //在Linux下调用是其他写法

            //p = rt.exec(command);
            ProcessBuilder builder = new ProcessBuilder("cmd", "/c", ffmpegPath, "-i", srcpath, "-ar", "24000", "-ab", "128k", "-vol", "512", "-f", "mp4", desfile);
//both read inputstream and errstream -ar 24000 -ab 128k -vol 200 -f mp4 temp.mp4
			
            builder.redirectErrorStream(true);
            Process process = builder.start();
            // Process process = Runtime.getRuntime().exec(command);
            boolean result = true;
/*            try {
                if (process.getErrorStream().read() != -1) {
                    result = false;
                    process.destroy();
                }
            } catch (IOException e) {
                e.printStackTrace();
                result = false;
            }*/
            String s;

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while ((s = bufferedReader.readLine()) != null) {
                System.out.println(s);
                doWithString(s);
            }

            process.waitFor();
            // readProcessOutput(p);

            // System.out.println("线程返回,转码后的文件大小为："+desFile.length()+",现在可以做其他操作了,比如重新写入ID3信息。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean _fixFFmpgePath() {
        URL url = W32Encoder.class.getClassLoader().getResource("ffmpeg_win32.exe");
        if (url == null) {
            return false;
        } else {
            ffmpegPath = new File(url.getPath()).getAbsolutePath();
			System.out.println(ffmpegPath);
        }
        return true;
    }
}
